function hasParamsFiled(filed) {
  return (filed !== undefined) && (filed !== '')
}

/**
 * 数据转换为树形（递归），示例：toTreeByRecursion(source, 'id', 'parentId', null, 'children')
 * @param {Array} source 数据
 * @param {String} idField 标识字段名称
 * @param {String} parentIdField 父标识字段名称
 * @param {Any} parentIdNoneValue 父级标识空值
 * @param {String} childrenField 子节点字段名称
 * @param {Object} treeOption tree树形配置
 */
function toTreeByRecursion(
  source = [],
  idField = 'id',
  parentIdField = 'parentId',
  parentIdNoneValue = '',
  childrenField = 'children',
  treeOption = undefined
) {
  const treeOptions = {
    enable: false, // 是否开启转tree插件数据
    keyField: 'key', // 标识字段名称，默认为key
    valueField: 'value', // 值字段名称，默认为value
    titleField: 'title', // 标题字段名称，默认为title

    keyFieldBind: 'id', // 标识字段绑定字段名称，默认为id
    valueFieldBind: 'id', // 值字段名称绑定字段名称，默认为id
    titleFieldBind: 'name' // 标题字段名称绑定字段名称，默认为name
  }
  // 合并tree树形配置
  if (treeOption) {
    Object.assign(treeOptions, treeOption)
  }

  // 对源数据深度克隆
  const cloneData = JSON.parse(JSON.stringify(source))
  return cloneData.filter(parent => {
    // 返回每一项的子级数组
    const branchArr = cloneData.filter(child => parent[idField] === child[parentIdField])

    // 绑定tree树形配置
    if (treeOptions.enable) {
      branchArr.map(child => {
        child[treeOptions.keyField] = child[treeOptions.keyFieldBind]
        child[treeOptions.valueField] = child[treeOptions.valueFieldBind]
        child[treeOptions.titleField] = child[treeOptions.titleFieldBind]
        return child
      })
    }

    // 如果存在子级，则给父级添加一个children属性，并赋值，否则赋值为空数组
    if (branchArr.length > 0) {
      parent[childrenField] = branchArr
    }

    // 绑定tree树形配置
    if (treeOptions.enable) {
      parent[treeOptions.keyField] = parent[treeOptions.keyFieldBind]
      parent[treeOptions.valueField] = parent[treeOptions.valueFieldBind]
      parent[treeOptions.titleField] = parent[treeOptions.titleFieldBind]
    }

    return parent[parentIdField] === parentIdNoneValue // 返回第一层
  })
}

function toTreeAndMap(data, idFiled = '_id', parentIdField = 'parentId') { // 递归树算法 将pid-id的数据库返回的json 转为树json
  const deepData = JSON.parse(JSON.stringify(data))

  // 删除 所有 children,以防止多次调用
  deepData.forEach(function(item) {
    delete item.children
  })

  // 将数据存储为 以id为KEY的map索引数据列
  const map = {}
  deepData.forEach(function(item) {
    map[item[idFiled]] = item
  })
  // console.log(map);

  const val = []
  deepData.forEach(function(item) {
    // 以当前遍历项，的pid,去map对象中找到索引的id
    var parent = map[item[parentIdField]]
    // 好绕啊，如果找到索引，那么说明此项不在顶级当中,那么需要把此项添加到，他对应的父级中
    if (parent) {
      (parent.children || (parent.children = [])).push(item) // 这里更改的是map对象的数据(索引数据)
      // console.log(map);
    } else {
      // 如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中，作为顶级
      val.push(item)
    }
  })

  return {
    treeData: val, // 树结构json数据 可以渲染html
    map // 索引数据 方便通过ID查找所有子节点ID
  }
}

module.exports = {
  hasParamsFiled,
  toTreeByRecursion,
  toTreeAndMap
}
